package main

import (
	"log"
	"time"

	"client2/config"
	"client2/mqtt"
)

// MQTT 功能测试程序
// 用途: 测试 MQTT 连接和数据发布
func main() {
	log.Println("=== MQTT 功能测试 ===")
	log.Println()

	// 1. 加载配置
	cfg := config.DefaultConfig()
	deviceCfg := config.LoadDeviceConfig()

	log.Printf("设备 ID: %s", deviceCfg.DeviceID)
	log.Printf("MQTT Broker: %s", cfg.MQTT.Broker)
	log.Println()

	// 2. 模拟 JWT token（实际应通过 ZKP 认证获取）
	// 在实际使用中，应该先调用 ZKP 认证获取真实的 JWT token
	token := "test_token_for_mqtt"
	log.Println("⚠️  使用测试 token（生产环境应使用 ZKP 认证获取的 JWT token）")
	log.Println()

	// 3. 创建 MQTT 客户端
	mqttConfig := &mqtt.Config{
		Broker:   cfg.MQTT.Broker,
		ClientID: deviceCfg.DeviceID,
		Username: cfg.MQTT.Username,
		Password: token,
		QoS:      cfg.MQTT.QoS,
		Retained: cfg.MQTT.Retained,
	}

	client, err := mqtt.NewClient(mqttConfig, token)
	if err != nil {
		log.Fatalf("❌ MQTT 连接失败: %v", err)
	}
	defer client.Disconnect()

	log.Println("✅ MQTT 客户端创建成功")
	log.Println()

	// 4. 创建发布器
	publisher := mqtt.NewPublisher(client)

	// 5. 发布测试数据
	log.Println("开始发布测试数据...")
	log.Println()

	// 5.1 发布设备上线状态
	log.Println("📤 发布设备上线状态...")
	status := &mqtt.DeviceStatus{
		DeviceID:  deviceCfg.DeviceID,
		Status:    "online",
		Timestamp: time.Now(),
		Metadata: map[string]interface{}{
			"version": "1.0.0",
			"test":    true,
		},
	}
	if err := publisher.PublishDeviceStatus(status); err != nil {
		log.Printf("❌ 发布状态失败: %v", err)
	}
	time.Sleep(1 * time.Second)

	// 5.2 发布传感器数据（温度）
	log.Println("📤 发布温度数据...")
	for i := 0; i < 5; i++ {
		tempData := &mqtt.SensorData{
			DeviceID:   deviceCfg.DeviceID,
			SensorType: "temperature",
			Value:      25.0 + float64(i)*0.5,
			Unit:       "°C",
			Timestamp:  time.Now(),
			Quality:    100,
		}
		if err := publisher.PublishSensorData(tempData); err != nil {
			log.Printf("❌ 发布温度数据失败: %v", err)
		}
		time.Sleep(500 * time.Millisecond)
	}

	// 5.3 发布传感器数据（湿度）
	log.Println("📤 发布湿度数据...")
	for i := 0; i < 5; i++ {
		humidityData := &mqtt.SensorData{
			DeviceID:   deviceCfg.DeviceID,
			SensorType: "humidity",
			Value:      60.0 + float64(i)*2.0,
			Unit:       "%RH",
			Timestamp:  time.Now(),
			Quality:    100,
		}
		if err := publisher.PublishSensorData(humidityData); err != nil {
			log.Printf("❌ 发布湿度数据失败: %v", err)
		}
		time.Sleep(500 * time.Millisecond)
	}

	// 5.4 发布告警
	log.Println("🚨 发布测试告警...")
	alert := &mqtt.Alert{
		DeviceID:   deviceCfg.DeviceID,
		AlertType:  "threshold_exceeded",
		Severity:   "high",
		Message:    "温度超过阈值（测试）",
		Value:      35.5,
		Threshold:  30.0,
		Timestamp:  time.Now(),
	}
	if err := publisher.PublishAlert(alert); err != nil {
		log.Printf("❌ 发布告警失败: %v", err)
	}
	time.Sleep(1 * time.Second)

	// 5.5 发布心跳
	log.Println("💓 发布心跳...")
	for i := 0; i < 3; i++ {
		metadata := map[string]interface{}{
			"cpu_usage":    15.5 + float64(i)*2.0,
			"memory_usage": 45.2 + float64(i)*1.5,
			"uptime":       i * 60,
		}
		if err := publisher.PublishHeartbeat(deviceCfg.DeviceID, metadata); err != nil {
			log.Printf("❌ 发布心跳失败: %v", err)
		}
		time.Sleep(1 * time.Second)
	}

	log.Println()
	log.Println("============================================================")
	log.Println("✅ MQTT 测试完成！")
	log.Println("============================================================")
	log.Println()
	log.Println("📋 已发布的数据:")
	log.Println("  - 1 条设备状态")
	log.Println("  - 5 条温度数据")
	log.Println("  - 5 条湿度数据")
	log.Println("  - 1 条告警")
	log.Println("  - 3 条心跳")
	log.Println()
	log.Println("📡 订阅测试:")
	log.Println("  在 Edge 服务器上运行以下命令查看数据:")
	log.Println()
	log.Println("  # 查看所有传感器数据")
	log.Println("  mosquitto_sub -h 172.18.2.214 -t 'sensors/#' -v")
	log.Println()
	log.Println("  # 查看设备状态")
	log.Println("  mosquitto_sub -h 172.18.2.214 -t 'devices/+/status' -v")
	log.Println()
	log.Println("  # 查看告警")
	log.Println("  mosquitto_sub -h 172.18.2.214 -t 'alerts/#' -v")
	log.Println()
	log.Println("  # 查看心跳")
	log.Println("  mosquitto_sub -h 172.18.2.214 -t 'devices/+/heartbeat' -v")
	log.Println()

	// 保持连接 5 秒，确保所有消息发送完成
	log.Println("等待 5 秒确保所有消息发送完成...")
	time.Sleep(5 * time.Second)
}
